home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
language
/
asxsrc.arc
/
ASMAIN.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-10
|
10KB
|
626 lines
/* asmain.c */
/*
* (C) Copyright 1989
* All Rights Reserved
*
* Alan R. Baldwin
* 721 Berkeley St.
* Kent, Ohio 44240
*/
#include <stdio.h>
#include <setjmp.h>
#include "asm.h"
VOID
main(argc, argv)
char *argv[];
{
register char *p;
register c, i;
struct area *ap;
FILE *afile();
inpfil = -1;
for (i=1; i<argc; ++i) {
p = argv[i];
if (*p == '-') {
++p;
while (c = *p++)
switch(c) {
case 'a':
case 'A':
++aflag;
break;
case 'g':
case 'G':
++gflag;
break;
case 'l':
case 'L':
++lflag;
break;
case 'o':
case 'O':
++oflag;
break;
case 's':
case 'S':
++sflag;
break;
case 'x':
case 'X':
xflag = 0;
break;
case 'q':
case 'Q':
xflag = 1;
break;
case 'd':
case 'D':
xflag = 2;
break;
default:
usage();
}
} else {
if (++inpfil == MAXFIL) {
fprintf(stderr, "too many input files\n");
exit(1);
}
sfp[inpfil] = afile(p, "", 0);
if (inpfil == 0) {
if (lflag)
lfp = afile(p, "lst", 1);
if (oflag)
ofp = afile(p, "rel", 1);
if (sflag)
tfp = afile(p, "sym", 1);
}
}
}
if (inpfil < 0)
usage();
syminit();
for (pass=0; pass<3; ++pass) {
if (gflag && pass == 1)
symglob();
if (aflag && pass == 1)
allglob();
if (oflag && pass == 2)
outgsd();
flevel = 0;
tlevel = 0;
ifcnd[0] = 0;
iflvl[0] = 0;
radix = 10;
line = 0;
page = 0;
stb[0] = 0;
lop = NLPP;
cfile = 0;
incfil = -1;
for (i = 0; i <= inpfil; i++)
rewind(sfp[i]);
ap = areap;
while (ap) {
ap->a_fuzz = 0;
ap->a_size = 0;
ap = ap->a_ap;
}
fuzz = 0;
dot->s_addr = 0;
dot->s_area = dca;
symp = dot;
minit();
while (getline()) {
++line;
cp = cb;
ep = eb;
ip = ib;
if (setjmp(jump_env) == 0)
asmbl();
if (pass == 2) {
diag();
list();
}
}
newdot(dot->s_area); /* Flush area info */
if (flevel || tlevel)
err('i');
}
if (oflag)
outchk(HUGE, HUGE); /* Flush */
if (sflag) {
lstsym(tfp);
} else
if (lflag) {
lstsym(lfp);
}
}
VOID
asmbl()
{
register struct mne *mp;
register struct sym *sp;
register struct tsym *tp;
register c;
struct area *ap;
struct expr e1;
char id[NCPS];
char opt[NCPS];
char fn[FILSPC];
char *p;
int d, n, uaf, uf;
laddr = dot->s_addr;
lmode = SLIST;
loop:
if ((c=endline()) == 0) { return; }
if (ctype[c] == DIGIT) {
if (flevel)
return;
n = 0;
while ((d = digit(c, 10)) >= 0) {
n = 10*n + d;
c = get();
}
if (c != '$' || get() != ':')
qerr();
tp = symp->s_tsym;
if (pass == 0) {
while (tp) {
if (n == tp->t_num) {
tp->t_flg |= S_MDF;
break;
}
tp = tp->t_lnk;
}
if (tp == NULL) {
tp=(struct tsym *) new (sizeof(struct tsym));
tp->t_lnk = symp->s_tsym;
tp->t_num = n;
tp->t_area = dot->s_area;
tp->t_addr = dot->s_addr;
symp->s_tsym = tp;
}
} else {
while (tp) {
if (n == tp->t_num) {
break;
}
tp = tp->t_lnk;
}
if (tp) {
if (pass == 1) {
fuzz = tp->t_addr - dot->s_addr;
tp->t_area = dot->s_area;
tp->t_addr = dot->s_addr;
} else {
phase(tp->t_area, tp->t_addr);
if (tp->t_flg & S_MDF)
err('m');
}
} else {
err('u');
}
}
goto loop;
}
if (ctype[c] != LETTER)
if (flevel) {
return;
} else {
qerr();
}
getid(id, c);
c = getnb();
if (c == ':') {
if (flevel)
return;
if ((c = get()) != ':') {
unget(c);
c = 0;
}
symp = lookup(id);
if (symp == dot)
err('.');
if (pass == 0)
if (symp->s_type != S_NEW &&
(symp->s_flag & S_ASG) == 0)
symp->s_flag |= S_MDF;
if (pass != 2) {
fuzz = symp->s_addr - dot->s_addr;
symp->s_type = S_USER;
symp->s_area = dot->s_area;
symp->s_addr = dot->s_addr;
} else {
if (symp->s_flag & S_MDF)
err('m');
phase(symp->s_area, symp->s_addr);
}
if (c) {
symp->s_flag |= S_GBL;
}
lmode = ALIST;
goto loop;
}
if (c == '=') {
if (flevel)
return;
if ((c = get()) != '=') {
unget(c);
c = 0;
}
expr(&e1, 0);
sp = lookup(id);
if (sp == dot) {
outall();
if (e1.e_flag || e1.e_base.e_ap != dot->s_area)
err('.');
} else
if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
err('m');
}
sp->s_type = S_USER;
sp->s_area = e1.e_base.e_ap;
sp->s_addr = laddr = e1.e_addr;
sp->s_flag |= S_ASG;
if (c) {
sp->s_flag |= S_GBL;
}
lmode = ALIST;
goto loop;
}
unget(c);
lmode = flevel ? SLIST : CLIST;
if ((mp = mlookup(id)) == NULL) {
if (!flevel)
err('o');
return;
}
switch (mp->m_type) {
case S_IF:
n = absexpr();
if (tlevel < MAXIF) {
++tlevel;
ifcnd[tlevel] = n;
iflvl[tlevel] = flevel;
if (n == 0) {
++flevel;
}
} else {
err('i');
}
lmode = ALIST;
laddr = n;
return;
case S_ELSE:
if (ifcnd[tlevel]) {
if (++flevel > (iflvl[tlevel]+1)) {
err('i');
}
} else {
if (--flevel < iflvl[tlevel]) {
err('i');
}
}
lmode = SLIST;
return;
case S_ENDIF:
if (tlevel) {
flevel = iflvl[tlevel--];
} else {
err('i');
}
lmode = SLIST;
return;
case S_PAGE:
lop = NLPP;
lmode = NLIST;
return;
default:
break;
}
if (flevel)
return;
switch (mp->m_type) {
case S_EVEN:
outall();
dot->s_addr = (dot->s_addr + 1) & ~1;
lmode = SLIST;
break;
case S_ODD:
outall();
dot->s_addr |= 1;
lmode = SLIST;
break;
case S_BYTE:
case S_WORD:
do {
expr(&e1, 0);
if (mp->m_type == S_BYTE) {
outrb(&e1, 0);
} else {
outrw(&e1, 0);
}
} while ((c = getnb()) == ',');
unget(c);
break;
case S_ASCII:
case S_ASCIZ:
if ((d = getnb()) == '\0')
qerr();
while ((c = getmap(d)) >= 0)
outab(c);
if (mp->m_type == S_ASCIZ)
outab(0);
break;
case S_BLK:
expr(&e1, 0);
outall();
dot->s_addr += e1.e_addr*mp->m_valu;
break;
case S_TITLE:
p = tb;
if (c = getnb()) {
do {
if (p < &tb[NTITL-1])
*p++ = c;
} while (c = get());
}
*p = 0;
unget(c);
lmode = SLIST;
break;
case S_SBTL:
p = stb;
if (c = getnb()) {
do {
if (p < &stb[NSBTL-1])
*p++ = c;
} while (c = get());
}
*p = 0;
unget(c);
lmode = SLIST;
break;
case S_MODUL:
getid(id, -1);
if (pass == 0) {
if (module[0])
err('m');
strncpy(module, id, NCPS);
}
lmode = SLIST;
break;
case S_GLOBL:
do {
getid(id, -1);
sp = lookup(id);
sp->s_flag |= S_GBL;
} while ((c = getnb()) == ',');
unget(c);
lmode = SLIST;
break;
case S_DAREA:
getid(id, -1);
uaf = 0;
uf = A_CON|A_REL;
if ((c = getnb()) == '(') {
do {
getid(opt, -1);
mp = mlookup(opt);
if (mp && mp->m_type == S_ATYP) {
++uaf;
uf |= mp->m_valu;
} else {
err('u');
}
} while ((c = getnb()) == ',');
if (c != ')')
qerr();
} else {
unget(c);
}
if (ap = alookup(id)) {
if (uaf && uf != ap->a_flag)
err('m');
} else {
ap = (struct area *) new (sizeof(struct area));
ap->a_ap = areap;
strncpy(ap->a_id, id, NCPS);
ap->a_ref = areap->a_ref + 1;
ap->a_flag = uaf ? uf : (A_CON|A_REL);
areap = ap;
}
newdot(ap);
lmode = SLIST;
break;
case S_ORG:
if (dot->s_area->a_flag & A_ABS) {
outall();
dot->s_addr = absexpr();
} else {
err('o');
}
lmode = SLIST;
break;
case S_RADIX:
if (more()) {
switch (getnb()) {
case 'b':
case 'B':
radix = 2;
break;
case '@':
case 'o':
case 'O':
case 'q':
case 'Q':
radix = 8;
break;
case 'd':
case 'D':
radix = 10;
break;
case 'h':
case 'H':
case 'x':